package com.fine.hair.manage.controller;

import cn.hutool.core.util.StrUtil;
import com.fine.hair.comm.dto.*;
import com.fine.hair.comm.utils.ApiResponse;
import com.fine.hair.comm.utils.PageInfo;
import com.fine.hair.comm.utils.Utils;
import com.fine.hair.comm.vo.IncomeInfo;
import com.fine.hair.comm.vo.IncomeStat;
import com.fine.hair.comm.vo.IncomeStatVo;
import com.fine.hair.manage.mapper.BranchMapper;
import com.fine.hair.manage.mapper.InventoryPutRecordMapper;
import com.fine.hair.manage.mapper.OrderMapper;
import com.fine.hair.manage.mapper.UserMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>财务控制类</p>
 *
 * @author mouseyCat
 * @date 2020/10/25 22:59
 */
@Api(tags = {"财务相关接口"})
@RestController
@RequestMapping("/finance/")
public class FinanceController {
    @Resource
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private BranchMapper branchMapper;
    @Autowired
    private InventoryPutRecordMapper inventoryPutRecordMapper;

    @PostMapping("income-stat")
    @ApiOperation("收入统计")
    public ApiResponse<List<IncomeStat>> incomeStat(@RequestBody IncomeStatDto dto) {

        IncomeStatVo vo = new IncomeStatVo();
        List<IncomeStat> list = orderMapper.incomeStatByDateAndBranchId(dto);
        vo.setTotalIncome(list.stream().map(IncomeStat::getOrderTotalMoney).reduce(BigDecimal.ZERO, BigDecimal::add));
        vo.setList(list);
        return ApiResponse.ofSuccess(list);
    }

    @PostMapping("income")
    @ApiOperation("收入")
    public ApiResponse income(@RequestBody IncomeDto dto) {
        if (StrUtil.isNotBlank(dto.getStartTime())) {
            // 处理 开始时间 和 结束时间
            String[] customDayStartAndEnd = getCustomDayStartAndEnd(dto.getStartTime(), dto.getEndTime());
            dto.setStartTime(customDayStartAndEnd[0]);
            dto.setEndTime(customDayStartAndEnd[1]);
        }
        List<IncomeInfo> incomeInfo = orderMapper.incomeByDateAndBranchId(dto);
        return ApiResponse.ofSuccess(incomeInfo);
    }


    // 》》》》》》》》》》》》》》》》》》》》各店数据统计《《《《《《《《《《《《《《《《《《《《《
    /*@GetMapping("gdsj/xmll/{branchId}/{lat}/{date}")
    @ApiOperation("各店数据统计，项目流量  branchId 门店ID  lat纬度（） date时间")
    public ApiResponse gdsjXmll(@RequestBody IncomeDto dto) {
        return ApiResponse.ofSuccess(incomeInfo);
    }*/

    @PostMapping("gdxhtj")
    @ApiOperation("各店消耗统计")
    public ApiResponse gdxhtj(@RequestBody GdxhtjDTO dto) {
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
        List<Map<String, Object>> list = branchMapper.selectGdxhtj(dto, pageInfo);
        pageInfo.setRecords(list);
        return ApiResponse.ofSuccess(pageInfo);
    }

    @PostMapping("gdxhygtj")
    @ApiOperation("各店下员工消耗统计")
    public ApiResponse gdxhygtj(@RequestBody GdxhtjDTO dto) {
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
        List<Map<String, Object>> list = branchMapper.selectGdxhygtj(dto, pageInfo);
        pageInfo.setRecords(list);
        return ApiResponse.ofSuccess(pageInfo);
    }

    @PostMapping("gdxhxmtj")
    @ApiOperation("各店下项目消耗统计")
    public ApiResponse gdxhxmtj(@RequestBody GdxhtjDTO dto) {
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
        List<Map<String, Object>> list = branchMapper.selectGdxhxmtj(dto, pageInfo);
        pageInfo.setRecords(list);
        return ApiResponse.ofSuccess(pageInfo);
    }


    @PostMapping("gdzctj")
    @ApiOperation("各店支出统计")
    public ApiResponse gdzctj(@RequestBody GdzctjDTO dto) {
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
        List<Map<String, Object>> list = inventoryPutRecordMapper.selectGdzctj(dto, pageInfo);
        pageInfo.setRecords(list);
        return ApiResponse.ofSuccess(pageInfo);
    }

    @PostMapping("gdsrtj")
    @ApiOperation("各店收入统计")
    public ApiResponse gdsrtj(@RequestBody GdzctjDTO dto) {
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
        List<Map<String, Object>> list = orderMapper.selectGdsrtj(dto, pageInfo);
        pageInfo.setRecords(list);
        return ApiResponse.ofSuccess(pageInfo);
    }


    @PostMapping("salarytj")
    @ApiOperation("工资统计")
    public ApiResponse gdsrtj(@RequestBody SalarytjDTO dto) {
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
        List<Map<String, Object>> list = userMapper.selectSalarytj(dto, pageInfo);
        pageInfo.setRecords(list);
        return ApiResponse.ofSuccess(pageInfo);
    }


    @PostMapping("gdsjtj/xmll")
    @ApiOperation("各店数据统计--项目流量")
    public ApiResponse gdxmlltj(@Validated @RequestBody GdsjtjDTO dto) {
        // 校验
        List<String> dates;
        String formatStr;
        if ("day".equals(dto.getLatitude())) { // 不得大于31天
            int days = Utils.getDayDiff(dto.getStartTime(), dto.getEndTime());
            if (days > 31) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getDayList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy-MM-dd";
        } else if ("month".equals(dto.getLatitude())) { // 不得大于12月
            int months = Utils.getMonthDiff(dto.getStartTime(), dto.getEndTime());
            if (months > 12) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getMonthList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy-MM";
        } else if ("year".equals(dto.getLatitude())) { // 不得超过3年
            int years = Utils.getYearDiff(dto.getStartTime(), dto.getEndTime());
            if (years > 3) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getYearList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy";
        } else {
            return ApiResponse.ofFailed("未知的纬度");
        }
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, Object> mapData;
        Integer flow;
        for (String date : dates) {
            flow = branchMapper.selectGdxmlltj(dto.getBranchIds(), date);
            mapData = new HashMap<>();
            mapData.put("dataByTime", Utils.stringTodate(date,formatStr).getTime()/1000);
            mapData.put("flow", Objects.isNull(flow) ? 0.00 : flow);
            data.add(mapData);
        }
        return ApiResponse.ofSuccess(data);
    }


    @PostMapping("gdsjtj/xhtj")
    @ApiOperation("各店数据统计--各店消耗統計")
    public ApiResponse gdxhtj(@Validated @RequestBody GdsjtjDTO dto) {
        // 校验
        List<String> dates;
        String formatStr;
        if ("day".equals(dto.getLatitude())) { // 不得大于31天
            int days = Utils.getDayDiff(dto.getStartTime(), dto.getEndTime());
            if (days > 31) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getDayList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy-MM-dd";
        } else if ("month".equals(dto.getLatitude())) { // 不得大于12月
            int months = Utils.getMonthDiff(dto.getStartTime(), dto.getEndTime());
            if (months > 12) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getMonthList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy-MM";
        } else if ("year".equals(dto.getLatitude())) { // 不得超过3年
            int years = Utils.getYearDiff(dto.getStartTime(), dto.getEndTime());
            if (years > 3) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getYearList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy";
        } else {
            return ApiResponse.ofFailed("未知的纬度");
        }
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, Object> mapData;
        BigDecimal consume;
        for (String date : dates) {
            consume = branchMapper.selectGdzbxhtj(dto.getBranchIds(), date);
            mapData = new HashMap<>();
            mapData.put("dataByTime", Utils.stringTodate(date,formatStr).getTime()/1000);
            mapData.put("consume", Objects.isNull(consume) ? 0.00 : consume);
            data.add(mapData);
        }
        return ApiResponse.ofSuccess(data);
    }


    @PostMapping("gdsjtj/gdsz")
    @ApiOperation("各店数据统计--各店收支对比")
    public ApiResponse gdszdbtj(@Validated @RequestBody GdsjtjDTO dto) {
        // 校验
        List<String> dates;
        String formatStr;
        if ("day".equals(dto.getLatitude())) { // 不得大于31天
            int days = Utils.getDayDiff(dto.getStartTime(), dto.getEndTime());
            if (days > 31) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getDayList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy-MM-dd";
        } else if ("month".equals(dto.getLatitude())) { // 不得大于12月
            int months = Utils.getMonthDiff(dto.getStartTime(), dto.getEndTime());
            if (months > 12) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getMonthList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy-MM";
        } else if ("year".equals(dto.getLatitude())) { // 不得超过3年
            int years = Utils.getYearDiff(dto.getStartTime(), dto.getEndTime());
            if (years > 3) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getYearList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy";
        } else {
            return ApiResponse.ofFailed("未知的纬度");
        }
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, Object> mapData;
        BigDecimal income;
        BigDecimal disburse;
        for (String date : dates) {
            income = branchMapper.selectGdszdbtj(dto.getBranchIds(), date, 1);
            disburse = branchMapper.selectGdszdbtj(dto.getBranchIds(), date, 2);
            mapData = new HashMap<>();
            mapData.put("dataByTime", Utils.stringTodate(date,formatStr).getTime()/1000);
            mapData.put("income", Objects.isNull(income) ? 0.00 : income);
            mapData.put("disburse", Objects.isNull(disburse) ? 0.00 : disburse);
            data.add(mapData);
        }
        return ApiResponse.ofSuccess(data);
    }


    @PostMapping("gdsjtj/zcyxhzb")
    @ApiOperation("各店数据统计--支出与消耗占比")
    public ApiResponse gdzcyxhzbtj(@Validated @RequestBody GdsjtjDTO dto) {
        // 校验
        List<String> dates;
        String formatStr;
        if ("day".equals(dto.getLatitude())) { // 不得大于31天
            int days = Utils.getDayDiff(dto.getStartTime(), dto.getEndTime());
            if (days > 31) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getDayList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy-MM-dd";
        } else if ("month".equals(dto.getLatitude())) { // 不得大于12月
            int months = Utils.getMonthDiff(dto.getStartTime(), dto.getEndTime());
            if (months > 12) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getMonthList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy-MM";
        } else if ("year".equals(dto.getLatitude())) { // 不得超过3年
            int years = Utils.getYearDiff(dto.getStartTime(), dto.getEndTime());
            if (years > 3) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getYearList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy";
        } else {
            return ApiResponse.ofFailed("未知的纬度");
        }
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, Object> mapData;
        BigDecimal consume;
        BigDecimal disburse;
        for (String date : dates) {
            consume = branchMapper.selectGdzbxhtj(dto.getBranchIds(), date);
            disburse = branchMapper.selectGdszdbtj(dto.getBranchIds(), date, 2);
            mapData = new HashMap<>();
            mapData.put("dataByTime", Utils.stringTodate(date,formatStr).getTime()/1000);
            mapData.put("consume", Objects.isNull(consume) ? 0.00 : consume);
            mapData.put("disburse", Objects.isNull(disburse) ? 0.00 : disburse);
            data.add(mapData);
        }
        return ApiResponse.ofSuccess(data);
    }


    @PostMapping("gdsjtj/xmxhyllzb")
    @ApiOperation("各店数据统计--项目消耗与流量比")
    public ApiResponse gdxmxhyllzbtj(@Validated @RequestBody GdsjtjDTO dto) {
        // 校验
        List<String> dates;
        String formatStr;
        if ("day".equals(dto.getLatitude())) { // 不得大于31天
            int days = Utils.getDayDiff(dto.getStartTime(), dto.getEndTime());
            if (days > 31) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getDayList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy-MM-dd";
        } else if ("month".equals(dto.getLatitude())) { // 不得大于12月
            int months = Utils.getMonthDiff(dto.getStartTime(), dto.getEndTime());
            if (months > 12) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getMonthList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy-MM";
        } else if ("year".equals(dto.getLatitude())) { // 不得超过3年
            int years = Utils.getYearDiff(dto.getStartTime(), dto.getEndTime());
            if (years > 3) {
                return ApiResponse.ofFailed("超出可查询范围");
            }
            dates = Utils.getYearList(dto.getStartTime(), dto.getEndTime());
            formatStr = "yyyy";
        } else {
            return ApiResponse.ofFailed("未知的纬度");
        }
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, Object> mapData;
        BigDecimal consume;
        Integer flow;
        for (String date : dates) {
            consume = branchMapper.selectGdxmxhtj(dto.getBranchIds(), date);
            flow = branchMapper.selectGdxmlltj(dto.getBranchIds(), date);
            mapData = new HashMap<>();
            mapData.put("dataByTime", Utils.stringTodate(date,formatStr).getTime()/1000);
            mapData.put("consume", Objects.isNull(consume) ? 0.00 : consume);
            mapData.put("flow", Objects.isNull(flow) ? 0.00 : flow);
            data.add(mapData);
        }
        return ApiResponse.ofSuccess(data);
    }

    /**
     * 处理查询时自定义的开始时间和结束时间
     *
     * @param start 日期 格式 yyyy-MM-dd
     * @param end   日期 格式 yyyy-MM-dd
     * @return 开始时间和结束时间的数组 下标0 为开始时间 下标1 为结束时间
     */
    public static String[] getCustomDayStartAndEnd(String start, String end) {
        // 兼容前端传 yyyy-MM-dd HH:mm:ss yyyy-MM-dd 两种情况
        String startTime = start.split(" ")[0] + " 00:00:00";
        String endTime = end.split(" ")[0] + " 23:59:59";
        String[] time = new String[2];
        time[0] = startTime;
        time[1] = endTime;
        return time;
    }

}
